import { observe, observable, action, computed, trace } from 'mobx'
import React, { Component, Fragment } from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import { observer } from 'mobx-react'

// 存放 数据
class Store {
    // 要做的事情：todos
    @observable todos = [];

    constructor(){
        observe(this.todos,change=>{
            console.log(change)
        })
    }
    @action.bound createTodo(title) {
        this.todos.unshift(new Todo(title));
    }
    // footer 中监听有几个剩余的
    @computed get left() {
        return this.todos.filter(todo => !todo.finished).length
    }
    @action.bound removeTodo(todo) {
        // remove 方法是 mobx 中的方法
        // 不然需要使用 根据id 来遍历删除
        this.todos.remove(todo);
    }
}

// 修饰 todos 的类
class Todo {
    // ID 是只读属性，不用 observable 来修饰
    id = Math.random();
    // todo 里面的内容，标题
    @observable title = '';
    // todo 是否完成了，是个标志位，默认为FALSE
    @observable finished = false;
    // 操作方便定义构造函数
    constructor(title, finished) {
        this.title = title;
        this.finished = finished;
    }
    @action.bound finishedToggle() {
        this.finished = !this.finished;
    }
}

// 初始化 store
const store = new Store();

@observer
class TodoItem extends Component {
    static PropTypes = {
        todo: PropTypes.shape({
            id: PropTypes.number.isRequired,
            title: PropTypes.string.isRequired,
            finished: PropTypes.bool.isRequired,
            finishedToggle: PropTypes.func
        }).isRequired,
        store: PropTypes.shape({
            todos: PropTypes.array.isRequired,
            delTodo: PropTypes.func.isRequired
        }).isRequired,
    };

    handleClick = e => {
        this.props.todo.finishedToggle()
    }
    render() {trace()
        const todo = this.props.todo;
        const store = this.props.store;
        return <Fragment>
            <input type="checkbox" className="toggle" checked={todo.finished} onClick={this.handleClick} />
            <span className={['title', todo.finished && 'finished'].join(' ')}>{todo.title}</span>
        </Fragment>
    }
}


// 所有 react 组件都需要使用 observer 修饰起来
@observer
class TodoList extends Component {
    // 编写参数类型校验代码
    static PropTypes = {
        store: PropTypes.shape({
            createTodo: PropTypes.func,
            todos: PropTypes.arrayOf(PropTypes.object).isRequired
        }).isRequired
    };
    // 声明 state 的默认值
    state = { inputValue: '' }

    handleSubmit = (e) => {
        // 由于是表单提交，为了防止整个页面提交
        e.preventDefault();
        // 分别把 store 和 inputValue 从 props 和 state 中取出
        const store = this.props.store;
        const inputValue = this.state.inputValue;

        store.createTodo(inputValue);
        // 最后把 state 值清空
        this.setState({
            inputValue: ''
        })
    }

    handleChange = (e) => {
        const inputValue = e.target.value;
        this.setState({
            inputValue
        })
    }

    render() {trace()
        // 第一部分是 header：是输入区，是用来输入一个新的todo
        // 第二部分是 ul: 展示区，展示所有的todo条目，可以删除或者finish条目
        // 第三个部分是 footer:提示区，比如提示用户还有多少个条目没有完成
        const store = this.props.store;

        const todos = store.todos
        return <div className="todo-list">
            <header>
                <form onSubmit={this.handleSubmit}>
                    <input type="text" onChange={this.handleChange} value={this.state.inputValue} className="input" placeholder="todo" />
                </form>
            </header>
            <ul>
                {todos.map((todo) => {
                    return <li key={todo.id} className="todo-item">
                        <TodoItem todo={todo} store={store} />
                        <span className="delete" onClick={()=>store.removeTodo(todo)}>X</span>
                    </li>
                })}
            </ul>
            <footer>{store.left} item(s) unfinished</footer>
        </div>
    }
}

ReactDOM.render(<TodoList store={store}></TodoList>, document.querySelector('#root'))